package com.xxcxcxcx.jobsystem.mixin.job.Blacksmith;


import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.xxcxcxcx.jobsystem.Main;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.item.ArmorItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TieredItem;
import net.minecraftforge.common.extensions.IForgeItem;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;

import java.util.UUID;

import static com.xxcxcxcx.jobsystem.common.Job.Blacksmith.Blacksmith.*;

@Mixin(Item.class)
public abstract class ItemStackMaxDamageMixin implements IForgeItem {

    @Shadow @Final private int maxDamage;

    @Shadow @Deprecated public abstract Multimap<Attribute, AttributeModifier> getDefaultAttributeModifiers(EquipmentSlot p_41388_);

    @Shadow @Final protected static UUID BASE_ATTACK_DAMAGE_UUID;

    @Shadow @Final protected static UUID BASE_ATTACK_SPEED_UUID;

    @Override
    public int getMaxDamage(ItemStack stack)
    {
        int num=this.maxDamage;
        if(stack.getItem() instanceof TieredItem || stack.getItem() instanceof ArmorItem){
            CompoundTag compoundTag=stack.getOrCreateTag();
            if(compoundTag.contains(Main.MOD_ID)){
                CompoundTag nbt = compoundTag.getCompound(Main.MOD_ID);
                if(nbt.contains(MakeTool+ToolLevel)){
                    num = Math.round(num*nbt.getFloat(MakeTool+Durable));
                }
            }else{
                num = num/10;
            }
        }
        return num;
    }
    private static final UUID[] ARMOR_MODIFIER_UUID_PER_SLOT = new UUID[]{UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B"), UUID.fromString("D8499B04-0E66-4726-AB29-64469D734E0D"), UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E"), UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150")};
    @Override
    public Multimap<Attribute, AttributeModifier> getAttributeModifiers(EquipmentSlot slot, ItemStack stack)
    {
        Multimap<Attribute, AttributeModifier> old= getDefaultAttributeModifiers(slot);
        if(!old.isEmpty()){
            if(stack.getItem() instanceof TieredItem){
                CompoundTag compoundTag=stack.getOrCreateTag();
                double damagespeed = old.get(Attributes.ATTACK_SPEED).iterator().next().getAmount();
                double damage = old.get(Attributes.ATTACK_DAMAGE).iterator().next().getAmount();
                if(compoundTag.contains(Main.MOD_ID)){
                    CompoundTag nbt = compoundTag.getCompound(Main.MOD_ID);
                    if(nbt.contains(MakeTool+ToolLevel)){
                        damage = damage*nbt.getFloat(MakeTool+Damage);
                    }
                }else{
                    damage = damage/10;
                }
                if(compoundTag.contains(Main.MOD_ID)){
                    CompoundTag nbt = compoundTag.getCompound(Main.MOD_ID);
                    if(nbt.contains(MakeTool+ToolLevel)){
                        damagespeed = damagespeed*nbt.getFloat(MakeTool+DamageSpeed);
                    }
                }else{
                    damagespeed = damagespeed*10;
                }
                ImmutableMultimap.Builder<Attribute, AttributeModifier> builder = ImmutableMultimap.builder();
                builder.put(Attributes.ATTACK_DAMAGE, new AttributeModifier(BASE_ATTACK_DAMAGE_UUID, "Change modifier", damage, AttributeModifier.Operation.ADDITION));
                builder.put(Attributes.ATTACK_SPEED, new AttributeModifier(BASE_ATTACK_SPEED_UUID, "Change modifier", damagespeed, AttributeModifier.Operation.ADDITION));
                return builder.build();
            }
            if(stack.getItem() instanceof ArmorItem){
                UUID uuid = ARMOR_MODIFIER_UUID_PER_SLOT[slot.getIndex()];
                CompoundTag compoundTag=stack.getOrCreateTag();
                ImmutableMultimap.Builder<Attribute, AttributeModifier> builder = ImmutableMultimap.builder();
                double Armor = old.get(Attributes.ARMOR).iterator().next().getAmount();
                double Armor_Toughness = old.get(Attributes.ARMOR_TOUGHNESS).iterator().next().getAmount();
                boolean knock = old.get(Attributes.KNOCKBACK_RESISTANCE).iterator().hasNext();
                double Knockback = knock?old.get(Attributes.KNOCKBACK_RESISTANCE).iterator().next().getAmount():0;
                if(compoundTag.contains(Main.MOD_ID)){
                    CompoundTag nbt = compoundTag.getCompound(Main.MOD_ID);
                    if(nbt.contains(MakeTool+ToolLevel)){
                        Armor = Armor*nbt.getFloat(MakeTool+Attributes.ARMOR.getDescriptionId());
                    }
                    if(nbt.contains(MakeTool+ToolLevel)){
                        Armor_Toughness = Armor_Toughness*nbt.getFloat(MakeTool+Attributes.ARMOR_TOUGHNESS.getDescriptionId());
                    }
                    if(nbt.contains(MakeTool+ToolLevel)){
                        Knockback = Knockback*nbt.getFloat(MakeTool+Attributes.KNOCKBACK_RESISTANCE.getDescriptionId());
                    }
                    String s2 = nbt.getString(MakeTool+ToolKind);
                    for(int i=0;i<ToolKinds.length;i++){
                        if(s2.equals(ToolKinds[i])){
                            if(i==0){
                                Armor *= 0.8;
                                Armor_Toughness *= 0.8;
                                Knockback *= 0.8;
                                builder.put(Attributes.MOVEMENT_SPEED, new AttributeModifier(uuid, "Change modifier", 0.01, AttributeModifier.Operation.ADDITION));
                            }
                            else if(i==1){
                                Armor *= 1.1;
                                Armor_Toughness *= 1.1;
                                Knockback *= 1.1;
                            }
                            else if(i==2){
                                Armor *= 1.2;
                                Armor_Toughness *= 1.2;
                                Knockback *= 1.2;
                                builder.put(Attributes.MOVEMENT_SPEED, new AttributeModifier(uuid, "Change modifier", -0.01, AttributeModifier.Operation.ADDITION));
                            }
                            else if(i==3){
                                Armor *= 1.2;
                                Armor_Toughness *= 1.2;
                                Knockback *= 1.2;
                                builder.put(Attributes.MOVEMENT_SPEED, new AttributeModifier(uuid, "Change modifier", 0.01, AttributeModifier.Operation.ADDITION));
                            }
                            else{
                                Armor *= 1.5;
                                Armor_Toughness *= 1.5;
                                Knockback *= 1.5;
                                builder.put(Attributes.MOVEMENT_SPEED, new AttributeModifier(uuid, "Change modifier", 0.01, AttributeModifier.Operation.ADDITION));
                                builder.put(Attributes.MAX_HEALTH, new AttributeModifier(uuid, "Change modifier", 2, AttributeModifier.Operation.ADDITION));
                            }
                        }
                    }
                }else{
                    Armor = Armor/10;
                    Armor_Toughness = Armor_Toughness/10;
                    Knockback = Knockback/10;
                }
                builder.put(Attributes.ARMOR, new AttributeModifier(uuid, "Change modifier", Armor, AttributeModifier.Operation.ADDITION));
                builder.put(Attributes.ARMOR_TOUGHNESS, new AttributeModifier(uuid, "Change modifier", Armor_Toughness, AttributeModifier.Operation.ADDITION));
                builder.put(Attributes.KNOCKBACK_RESISTANCE, new AttributeModifier(uuid, "Change modifier", Knockback, AttributeModifier.Operation.ADDITION));
                return builder.build();
            }
        }
        return old;
    }
}
